const X2JS = require('x2js');

const Models = require('../../models');
const logger = require('../../utils/logger');
const RuntimeError = require('../../utils/error');
const { wxPaySign } = require('../../lib/wxPay')
const acQueue = require('../../lib/account-creation-queue');
const { insertLog } = require(__base + '/lib/serviceLogger');

module.exports = async (req, res) => {
  const io = req.app.get('io');
  if (!req.body.xml) {
    logger.error('wxpaycb: XML missing.');
    throw new RuntimeError(400, 'XML missing.')
  }

  logger.info(req.body.xml);

  // 签名返回数据
  let keys = Object.keys(req.body.xml);
  let data = {};
  for (let k of keys) {
    if (k === 'sign') {
      continue;
    }
    data[k] = req.body.xml[k][0];
  }
  let signature = wxPaySign(data);
  logger.info('My signature:', signature);
  insertLog('info', `wxpay ${data.out_trade_no} ${signature}`)

  if (signature === req.body.xml.sign[0]) {
    if (req.body.xml.return_code[0] == "SUCCESS") {
      try {
        let acReq = await Models.AccountCreationRequest.findOne({ 
          where: { 
            billNo: data.out_trade_no,
            status: 'initial'
          } 
        });
        if (acReq) {
          acReq.status = 'paid';
          await acReq.save();

          acQueue.add(acReq);

          logger.info('Order paid:', acReq.get({ plain: true }));
          io.sendPaidResult(data.out_trade_no, { code: 0, message: 'success' });
          return res.send("<xml><return_code><![CDATA[SUCCESS]]</return_code><return_msg><![CDATA[OK]]></return_msg></xml>");
        }
      } catch (error) {
        logger.error(error.message);
        insertLog('error', `${data.out_trade_no} ${error.message}`)
        io.sendPaidResult(data.out_trade_no, { code: 999, message: error.message });
        return res.send('fail');
      }
    } else {
      logger.error('wxPayment failed!');
      insertLog('error', `${data.out_trade_no} wxPayment failed!`)
      io.sendPaidResult(data.out_trade_no, { code: 999, message: req.body.xml.return_msg[0] });
      return res.send('fail');
    }
    
  } else {
    logger.error('Signature invalid!', req.body);
    insertLog('error', `${data.out_trade_no} Signature invalid! ${JSON.stringify(req.body)}`)
    io.sendPaidResult(data.out_trade_no, { code: 999, message: 'Signature invalid!' });
    return res.send('fail');
  }
}